Geschachtelter SELECT

Dies ist Teil 4 von 10 der Serie Performance-Workshop

Hier erklären wir Ihnen, wie Sie am besten geschachtelte SELECTs verwenden oder wie Sie diese umgehen können.

Geschachtelte SELECTs kommen sehr häufig in Programmen vor, da die Kopfinformation eines Objekts meistens in einer Tabelle und die Positionsinformationen in einer zweiten Tabelle gespeichert werden. Oftmals kommen noch andere Tabellen hinzu:

  • Verkaufsbelege: VBAK -> VBAP -> VBEP
  • Einkaufsbelege: EKKO -> EKPO -> EKBE
  • Materialstamm: MARA -> MARC -> MARD

Der geschachtelte SELECT

Im folgenden Beispiel werden Verkaufsbelege mit den dazugehörigen Positionen gelesen.

*** Lesen von Verkaufsbelegen
SELECT * FROM VBAK INTO TABLE t_vbak WHERE ….
LOOP AT t_vbak.
  SELECT * FROM vbap APPENDING TABLE t_vbap
   WHERE vbeln = t_vbak-vbeln.
   …
ENDLOOP.

Schlecht an diesem Coding ist, dass für jeden Verkaufsbeleg ein SELECT gemacht wird, um die Positionsdaten nachzulesen.

Diesen geschachtelten SELECT kann man auf zwei Arten schneller und effizienter machen:

FOR ALL ENTRIES

Diese Variante ist besser, da der SELECT auf die VBAP nur einmal ausgeführt wird. Ausserdem spart man den LOOP über die Tabelle VBAP.

Noch mal zur Erinnerung: Die Verbindung mit der Datenbank sollte auf ein Minimum reduziert werden, da sie am meisten Zeit beansprucht.

Stellen Sie bei dieser Variante unbedingt sicher, dass die Tabelle, die Sie unter “FOR ALL ENTRIES” angeben auch gefüllt ist!!

Es werden sonst alle Daten aus der in der FROM-Klausel angegebenen Tabelle gelesen!!

SELECT * FROM VBAK INTO TABLE t_vbak WHERE ….
IF sy-dbcnt > 0.
  SELECT * FROM vbap INTO TABLE t_vbap
     FOR ALL ENTRIES IN t_vbak
   WHERE vbeln = t_vbak-vbeln.
ENDIF.

INNER JOIN

Wenn es sinnvoll ist, dass nur bestimmte Felder aus den Beleg-Tabellen VBAK und VBAP selektiert werden, dann kann ein Inner Join verwendet werden. Auch dieser ist in der Regel schneller, als zwei unabhängige SELECTS, da schon auf Datenbankebene die meiste Arbeit gemacht wird.

DATA:
  BEGIN OF t_vbakap OCCURS 0,
    vbeln TYPE vbeln,
    posnr TYPE posnr,
    matnr TYPE matnr,
    pstyv TYPE pstyv,
  END OF t_vbakap.

*** Selektion der Felder aus VBAK und VBAP
SELECT vbap~vbeln  vbap~vbeln vbap~matnr vbap~pstyv
  FROM vbak
 INNER JOIN vbap ON vbap~vbeln = vbak~vbeln
 WHERE vbak~vbeln IN s_vbeln
   AND vbak~auart IN s_auart
   AND vbap~matnr IN s_matnr.

Enno Wulff
Series Navigation<< SELECT mit FeldleisteDatenbank-Hints >>